//
// Created by zhouzechao on 2019-09-17.
//
#include <unistd.h>
#include "MetadataRetriever.h"
#include "AndroidLog.h"

// public
MetadataRetriever::MetadataRetriever() {
    av_register_all();
    avformat_network_init();
    state = NULL;
    mMetadata = new Metadata();
}

MetadataRetriever::~MetadataRetriever() {
    release();
    avformat_network_deinit();
    delete mMetadata;
    mMetadata = NULL;
}

void MetadataRetriever::release() {
    Mutex::Autolock lock(mLock);
    release(&state);
}

int MetadataRetriever::setDataSource(const char *url) {
    Mutex::Autolock lock(mLock);
    return setDataSource(&state, url, NULL);
}

status_t
MetadataRetriever::setDataSource(const char *url, int64_t offset, const char *headers) {
    Mutex::Autolock lock(mLock);
    return setDataSource(&state, url, headers);
}

const char *MetadataRetriever::getMetadata(const char *key) {
    Mutex::Autolock lock(mLock);
    return extractMetadata(&state, key);
}

// 提取Metadata数据
const char *getMetadata(const char *key, int chapter) {

}

// 提取Metadat数据
int getMetadata(AVDictionary **metadata) {

}

// 提取专辑/封面图片
int getEmbeddedPicture(AVPacket *pkt) {

}

// 取得某个时刻的图像
int getFrame(int64_t timeUs, AVPacket *pkt) {

}

// 取得某个时刻的图像
int getFrame(int64_t timeus, AVPacket *pkt, int width, int height) {

}


// private

/**
 * 初始化
 * @param ps
 */
void MetadataRetriever::init(MetadataState **ps) {
    MetadataState *state = *ps;

    if (state && state->pFormatCtx) {
        avformat_close_input(&state->pFormatCtx);
    }

    if (state && state->fd != -1) {
        close(state->fd);
    }

    if (!state) {
        state = static_cast<MetadataState *>(av_mallocz(sizeof(MetadataState)));
    }

    state->pFormatCtx = NULL;
    state->audioStreamIndex = -1;
    state->videoStreamIndex = -1;
    state->audioStream = NULL;
    state->videoStream = NULL;
    state->fd = -1;
    state->offset = 0;
    state->headers = NULL;

    *ps = state;
}

/**
 * 释放资源
 * @param ps
 */
void MetadataRetriever::release(MetadataState **ps) {
    MetadataState *state = *ps;
    if (!state) {
        return;
    }
    if (state->audioStream && state->audioStream->codec) {
        avcodec_close(state->audioStream->codec);
    }
    if (state->videoStream && state->videoStream->codec) {
        avcodec_close(state->videoStream->codec);
    }
    if (state->pFormatCtx) {
        avformat_close_input(&state->pFormatCtx);
    }
    if (state->fd != -1) {
        close(state->fd);
    }
    if (state->pSwsContext) {
        sws_freeContext(state->pSwsContext);
        state->pSwsContext = NULL;
    }
    if (state->pCodecContext) {
        avcodec_close(state->pCodecContext);
        av_free(state->pCodecContext);
    }
    if (state->pSwsContext) {
        sws_freeContext(state->pSwsContext);
    }
    if (state->pScaleCodecContext) {
        avcodec_close(state->pScaleCodecContext);
        av_free(state->pScaleCodecContext);
    }
    if (state->pScaleSwsContext) {
        sws_freeContext(state->pScaleSwsContext);
    }
    av_freep(&state);
    ps = NULL;
}

// 解析metadata数据
const char *MetadataRetriever::extractMetadata(MetadataState **ps, const char *key) {
    char* value = NULL;
    MetadataState *state = *ps;

    if (!state || !state->pFormatCtx) {
        return value;
    }

    return mMetadata->extractMetadata(state->pFormatCtx, state->audioStream, state->videoStream,
                                      key);
}